package com.lmk.mkcc.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.lmk.mkcc.domain.KillActivity;
import com.lmk.mkcc.domain.KillCourse;
import com.lmk.mkcc.enums.GlobalErrorCode;
import com.lmk.mkcc.mapper.KillActivityMapper;
import com.lmk.mkcc.service.IKillActivityService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.lmk.mkcc.service.IKillCourseService;
import com.lmk.mkcc.util.AssertUtil;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kun
 * @since 2022-10-20
 */
@Service
@Transactional
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private IKillCourseService killCourseService;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void publish(Long activityId) {
        // 1.判断活动是否为空
        KillActivity killActivity = selectById(activityId);
        AssertUtil.isNotNull(killActivity, GlobalErrorCode.ERROE);
        // 2.判断状态
        boolean equals = killActivity.getPublishStatus().equals(0);
        AssertUtil.isTrue(equals,GlobalErrorCode.STATUS_IS_ERROR);
        // 判断活动发布时间是否在开始秒杀时间之前
        boolean after = killActivity.getStartTime().after(new Date());
        AssertUtil.isTrue(after,GlobalErrorCode.DATE_OUT_ERROR);
        // 3.判断秒杀课活动中是否有秒杀课程
        EntityWrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id",activityId);
        List<KillCourse> killCourses = killCourseService.selectList(wrapper);
        AssertUtil.isNotNull(killCourses,GlobalErrorCode.NO_KILLCOURSE_ERROR);
        // 4.设置信号量
        for (KillCourse killCourse : killCourses) {
            Long killCourseId = killCourse.getId();
            RSemaphore semaphore = redissonClient.getSemaphore(activityId + ":" + killCourseId);
            boolean b = semaphore.trySetPermits(killCourse.getKillCount());
            if (b){
                // 放入redis中
                redisTemplate.opsForHash().put("activity:" + activityId,killCourse.getId().toString(),killCourse);
                // 修改课程状态以及发布时间
                killCourse.setPublishTime(new Date());
                killCourse.setPublishStatus(1);
                killCourseService.updateById(killCourse);
            }

        }
        // 修改秒杀活动状态，发布时间
        killActivity.setPublishStatus(1);
        killActivity.setPublishTime(new Date());
        updateById(killActivity);

    }

    @Override
    public void cancelpublish(Long activityId) {
        EntityWrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id",activityId);
        List<KillCourse> killCourses = killCourseService.selectList(wrapper);
        for (KillCourse killCourse : killCourses) {
            killCourse.setOfflineTime(new Date());
            killCourse.setPublishStatus(2);
            killCourseService.updateById(killCourse);
        }
        // 修改秒杀活动状态，发布时间
        KillActivity killActivity = selectById(activityId);
        killActivity.setPublishStatus(2);
        updateById(killActivity);
        // 删除redis中的数据
        redisTemplate.delete("activity:" + activityId);
    }
}
